using System.IO;
using System.Xml.Linq;
using TDUnit.Common.TestData;
using TDUnit.Common.TestDataParser;

namespace TDUnit.TestDataParsers.XmlParser
{
    public class XmlTestDataParser : ITestDataParser
    {
        #region Public properties

        public string TestDataString { get; set; }
        public string TestDataFilePath { get; set; }

        #endregion

        #region Public methods

        public TestData Parse()
        {
            AssertDataSetIsPresent();

            var doc = GetXDocument();
            var dataset = new TestData();

            var docProcessor = new DocumentProcessorPipeline().WithProcessor(new ImportElementProcessor()).WithProcessor(new TestDataElementsProcessor(dataset));
            docProcessor.Process(doc);

            return dataset;
        }

        public XmlTestDataParser WithTestDataString(string testDataString)
        {
            TestDataString = testDataString;
            return this;
        }

        public XmlTestDataParser WithTestDataPath(string testDataFilePath)
        {
            TestDataFilePath = testDataFilePath;
            return this;
        }

        #endregion

        #region Helper methods

        private XDocument GetXDocument()
        {
            var loadOpts = LoadOptions.SetLineInfo;
            return string.IsNullOrEmpty(TestDataFilePath)
                       ? XDocument.Load(new StringReader(TestDataString), loadOpts)
                       : XDocument.Load(TestDataFilePath, loadOpts);
        }

        private void AssertDataSetIsPresent()
        {
            if (string.IsNullOrEmpty(TestDataString) && string.IsNullOrEmpty(TestDataFilePath))
                throw new TestDataParserException("You must set the TestDataString to a valid dataset or set the TestDataFilePath to the path of a valid dataset file.");
        }


        #endregion
    }
}